package com.yjz.media.study.util.camera;

import android.content.ContentValues;
import android.content.Context;
import android.os.Build;
import android.provider.MediaStore;
import android.util.Log;
import android.util.Size;

import androidx.annotation.NonNull;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.LifecycleOwner;

import com.blankj.utilcode.util.ToastUtils;
import com.google.common.util.concurrent.ListenableFuture;

import java.text.SimpleDateFormat;
import java.util.Locale;

/**
 * 作用 :
 * 作者 : yjz
 * 时间 : 2023/11/8 11:30
 */
public class CameraHelper {

    private static volatile CameraHelper cameraHelper = new CameraHelper();
    private ImageAnalysis imageAnalysisUseCase;
    private ImageCapture imageCaptureUseCase;
    private CameraImageByteAnalyzer cameraImageByteAnalyzer;

    private CameraHelper() {
    }

    public static CameraHelper getInstance() {
        if (cameraHelper == null) {
            synchronized (CameraHelper.class) {
                if (cameraHelper == null) {
                    cameraHelper = new CameraHelper();
                }
            }
        }
        return cameraHelper;
    }

    /**
     * cameraX 图像分析的数据回调接口
     */
    public CameraImageByteAnalyzer.IPushDataListener pushDataListener;

    public void setPushDataListener(CameraImageByteAnalyzer.IPushDataListener pushDataListener) {
        this.pushDataListener = pushDataListener;
    }

    /**
     * 开始相机预览
     *
     * @param context 上下文
     */
    public void startCamera(Context context, LifecycleOwner lifecycleOwner, Preview.SurfaceProvider surfaceProvider) {
        ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(context);
        cameraProviderFuture.addListener(() -> {
            try {
                // Used to bind the lifecycle of cameras to the lifecycle owner
                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();

                Preview preview = new Preview.Builder()
                        // 设置预览大小
                        .setTargetResolution(new Size(720, 1280))
                        .build();

                preview.setSurfaceProvider(surfaceProvider);

                // 如果想要做什么动作就需要实现什么动作

                // 1.拍照
                imageCaptureUseCase = new ImageCapture.Builder()
                        // 拍照大小
                        .setTargetResolution(new Size(720, 1280))
                        .build();

                // 2.相机数据分析
                imageAnalysisUseCase = new ImageAnalysis.Builder()
                        // 最 后一帧
                        .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
                        .setImageQueueDepth(1) // 队列中只保持一个
                        // 数据分析大小
                        .setTargetResolution(new Size(720, 1280))
                        .build();
                cameraImageByteAnalyzer = new CameraImageByteAnalyzer();
                cameraImageByteAnalyzer.setPushDataListener(pushDataListener);
                imageAnalysisUseCase.setAnalyzer(ContextCompat.getMainExecutor(context), cameraImageByteAnalyzer);

                // 3.录视频

                // 使用后置摄像头
                CameraSelector backCamera = CameraSelector.DEFAULT_BACK_CAMERA;
                // 注册需要使用的UseCase
                cameraProvider.bindToLifecycle(lifecycleOwner, backCamera, preview, imageCaptureUseCase, imageAnalysisUseCase);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, ContextCompat.getMainExecutor(context));
    }

    /**
     * 拍照
     *
     * @param context 上下文
     */
    public void takePhoto(Context context) {
        if (imageCaptureUseCase == null) return;

        String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(System.currentTimeMillis());

        ContentValues contentValues = new ContentValues();
        contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, format);
        contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
            contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/CameraX-Image");
        }
        ImageCapture.OutputFileOptions outputOptions = new ImageCapture.OutputFileOptions.Builder(context.getContentResolver(),
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                contentValues).build();

        imageCaptureUseCase.takePicture(outputOptions, ContextCompat.getMainExecutor(context), new ImageCapture.OnImageSavedCallback() {
            @Override
            public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
                String msg = "Photo capture succeeded: " + outputFileResults.getSavedUri();
                ToastUtils.showShort(msg);
                Log.d("TAG", msg);
            }

            @Override
            public void onError(@NonNull ImageCaptureException exception) {
                Log.e("TAG", "Photo capture failed: ", exception);
            }
        });
    }

    /**
     * 停止推流
     */
    public void stopPush() {
        cameraImageByteAnalyzer.stopPush();
    }
}
